# -*- coding: utf-8 -*-
# @Author: Jerry
# @Date:   2022-02-21 17:10:14
# @Last Modified by:   Jerry
# @Last Modified time: 2022-03-01 15:31:20

'''
http://www.woshicver.com/
目标
学习图像的几种算术运算，例如加法，减法，按位运算等。
您将学习以下功能：cv.add，cv.addWeighted 等。
'''

# **********
'''
图像加法 cv.add()
您可以通过OpenCV函数cv.add() 或 仅通过numpy操作res = img1 + img2添加两个图像。
两个图像应具有相同的深度和类型，或者第二个图像可以只是一个标量值。
OpenCV加法和Numpy加法之间有区别。OpenCV加法是饱和运算，而Numpy加法是模运算。
'''
import os
rootpath = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
datapath = os.path.join(rootpath,'data')
imgpath = lambda name: os.path.join(datapath,name)

import numpy as np
import cv2 as cv

x = np.uint8([240]) # [240]
y = np.uint8([5])   # [5]
z = cv.add(x,y)  # [[245]], 维度发生变化, 加法返回计算结果
print(z)
# 当添加两个图像时，它将更加可见。OpenCV功能将提供更好的结果。
# 因此，始终最好坚持使用OpenCV功能。


# **********
'''
图像融合 cv.addWeighted()
融合也是图像加法，但是对图像赋予不同的权重，以使其具有融合或透明的感觉
根据以下等式添加图像：
G(x)=(1−α)f0(x) + αf1(x) + γ
通过从 α 从 0 → 1 更改，您可以在一个图像到另一个图像之间执行很酷的过渡。
cv.addWeighted() 在图像上应用以下公式 dst = α*img1 + β*img2 + γ
'''
img1 = cv.imread(imgpath('ml.png'))
# print help(img1)
print 'img1:',img1.shape,img1.size
img2 = cv.imread(imgpath('opencv-logo.png'))
print 'img2:',img2.shape,img2.size
img2ROI = img2[100:480,100:408] # 在img2上取与img1相同的一个ROI区域对象
dst = cv.addWeighted(img1,0.7,img2ROI,0.3,0) # 两张图片的shape参数必须相同，否则会报错
# cv.imshow('dst',dst)
# img2[100:480,100:408] = dst[:,:]
img2[100:480,100:408] = dst
# cv.imshow('img2',img2)
# cv.waitKey(0)
# cv.destroyAllWindows()


# **********
'''
按位运算
这包括按位 AND、 OR、NOT 和 XOR 操作。
它们在提取图像的任何部分(我们将在后面的章节中看到)、定义和处理非矩形 ROI 等方面非常有用。

以下例子演示，如何改变一个图像的特定区域。
目标：我想把 OpenCV 的标志放在一个图像上面。
如果我添加两个图像，它会改变颜色。如果我混合它，我得到一个透明的效果。但我希望它是不透明的。
如果是一个矩形区域，我可以使用 ROI，就像我们在上一章中所做的那样。
但是 OpenCV 的 logo 不是长方形的。所以你可以使用如下的按位操作来实现:
'''
# 加载两张图片
img1 = cv.imread(imgpath('messi5.jpg'))
# print img1.shape # (342, 548, 3)
img2 = cv.imread(imgpath('opencv-logo-white.png'))  # 图片无背景色，只包含opencv logo
# print img2.shape # (238, 180, 3)
# 我想把logo放在左上角，所以我创建了ROI
rows,cols,channels = img2.shape
roi = img1[0:rows,0:cols]
# 现在创建logo的掩码，并同时创建其相反掩码
img2gray = cv.cvtColor(img2,cv.COLOR_BGR2GRAY)
ret,mask = cv.threshold(img2gray,10,255,cv.THRESH_BINARY)
mask_inv = cv.bitwise_not(mask)
# 现在将ROI中logo的区域涂黑
img1_bg = cv.bitwise_and(roi,roi,mask=mask_inv)
# 仅从logo图像中提取logo区域
img2_fg = cv.bitwise_and(img2,img2,mask=mask)
# 将logo放入ROI并修改主图像
dst = cv.add(img1_bg,img2_fg)
img1[0:rows,0:cols] = dst
cv.imshow('res',img1)
cv.waitKey(0)
cv.destroyAllWindows()









